package com.eastseeway.radioproject.views;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.eastseeway.radioproject.R;

public class WatchPanelView extends View {

    private int openAngle = 120;//底部开口角度
    private float singleScaleAngle ; //每一刻度的角度
    private int mScaleColor;//刻度的颜色
    private Paint mScalePaint;//刻度的画笔

    private int mMaxScale = 60;
    private int mCurrentScale = 0;//设置的目标刻度

    private int mWidth;
    private int mHeight;
    private int mRadius;
    private Rect mSrcRect;
    private Rect mDesRect;
    private int mBgResId;
    private Bitmap mBgImage = null;
    private Bitmap mIndicatorImg;
    private Paint mTextPaint;
    private Path mScaleValuePath;
    private float mLongLine;
    private Rect mTextRect;
    private RectF mRectFInnerArc;
    private Rect mIndicatorSrcRect;
    private Rect mIndicatorDesRect;


    public WatchPanelView(Context context) {
        this(context,null);
    }

    public WatchPanelView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public WatchPanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context,attrs);
        initPaints();
    }

    private void initPaints() {
//        刻度的画笔
        mScalePaint = new Paint();
        mScalePaint.setColor(mScaleColor);
        mScalePaint.setStyle(Paint.Style.STROKE);
        mScalePaint.setStrokeWidth(2f);
        mScalePaint.setAntiAlias(true);
//          文字的画笔
        mTextPaint = new Paint();
        mTextPaint.setColor(getColor(R.color.white));
        mTextPaint.setStyle(Paint.Style.STROKE);
//        mTextPaint.setStrokeWidth(2f);
        mTextPaint.setAntiAlias(true);

        mScaleValuePath = new Path();
        mTextRect = new Rect();
        mRectFInnerArc = new RectF();

        Paint rectFPaint = new Paint();
        rectFPaint.setColor(getColor(R.color.white));
        rectFPaint.setStyle(Paint.Style.FILL);

//        mHourPaint = new Paint();
//        mHourPaint.setColor(mHourColor);
//        mHourPaint.setStyle(Paint.Style.STROKE);
//        mHourPaint.setStrokeWidth(4f);
//        mHourPaint.setStrokeCap(Paint.Cap.ROUND);
//        mHourPaint.setAntiAlias(true);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TimePanelView);
        openAngle = typedArray.getInteger(R.styleable.TimePanelView_open_angle, 120);
        mScaleColor = typedArray.getColor(R.styleable.TimePanelView_scale_color1, getColor(R.color.white));
        mBgResId = typedArray.getResourceId(R.styleable.TimePanelView_background_image, -1);
        if (mBgResId != -1) {
            mBgImage = BitmapFactory.decodeResource(getResources(), mBgResId);
        }
        mIndicatorImg = BitmapFactory.decodeResource(getResources(),R.mipmap.icon_radio_indicator);
        typedArray.recycle();
    }

    private int getColor(int color){
        return getResources().getColor(color, getContext().getTheme());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int widthTargetSize = widthSize - getPaddingStart() - getPaddingEnd();

        int heightTargetSize = heightSize - getPaddingTop() - getPaddingBottom();

//        判断大小，取小的
        int targetSize = Math.min(widthTargetSize,heightTargetSize);
//        Log.e("12121","widthTargetSize:"+widthTargetSize);
//        Log.e("12121","heightTargetSize:"+heightTargetSize);
        setMeasuredDimension(targetSize,targetSize);
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        mRadius = mWidth / 2 ;
//        singleScaleAngle = (float) (360 - openAngle) / (mMaxScale -1);
        mLongLine = mRadius - 15;
        onMaxScaleChanged();
        mTextPaint.getTextBounds("0", 0, "0".length(), mTextRect);
        mRectFInnerArc.set(15+mTextRect.height(),
                15+mTextRect.height(),
                mRadius*2-15-mTextRect.height(),
                mRadius*2-15-mTextRect.height());
//        从图片中获取要展示的部分
        mSrcRect = new Rect(0,0,mBgImage.getWidth(),mBgImage.getHeight());
//        要填充图片的地方
        mDesRect = new Rect(0+30, 0+30, mWidth-30, mHeight-30);

        mIndicatorSrcRect = new Rect(0,0,mIndicatorImg.getWidth(),mIndicatorImg.getHeight());
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBgImage,mSrcRect,mDesRect,mTextPaint);
//        画刻度线
        drawScale(canvas);
//        画刻度值
//        drawScaleValue(canvas);
        drawScaleV(canvas);
//        画指针
        drawPointer(canvas);
    }

    private void drawScaleV(Canvas canvas){
        for (int i = 0; i < mMaxScale +1; i=i+5) {
            String text = String.valueOf(i);
            mTextPaint.getTextBounds(text,0,text.length(), mTextRect);
            // 粗略把文字的宽度视为圆心角2*θ对应的弧长，利用弧长公式得到degree，下面用于修正角度
            float degree = (float) (180 * mTextRect.width() / 2 / (Math.PI * (mRadius - 15 - mTextRect.height())));
            mScaleValuePath.reset();
            mScaleValuePath.addArc(
                    mRectFInnerArc,
                    150 + i * (singleScaleAngle) - degree, // 正起始角度减去θ使文字居中对准长刻度
                    240
            );
//            canvas.drawRect(mRectFInnerArc,mMRectFPaint);
            canvas.drawTextOnPath(text, mScaleValuePath, 0, 0, mTextPaint);
        }
    }

//    这种方式绘制的刻度值位置不准
    private void drawScaleValue(Canvas canvas) {
//        canvas.save();
//        canvas.rotate(-30,mRadius,mRadius);
        for (int i = 0; i < mMaxScale +1; i++) {
            if ((i) % 5 == 0) {
                float v = i * singleScaleAngle;//当前刻度*每一刻度的角度=当前刻度的总角度
                String text = String.valueOf(i);
                float textWidth = mTextPaint.measureText(text);
                if (v <= 30){
                    float degree = 30 - v;
                    float neighborLine = (float) Math.cos(degree/180f*Math.PI) * mLongLine;
                    float x = mRadius - neighborLine;
                    float duiLine = (float) (Math.sin(degree/180f*Math.PI) * mLongLine);
                    float y = mRadius + duiLine;
                    canvas.drawText(text,x + textWidth /2,y + textWidth /2, mTextPaint);
                }else if (v <= 120){
                    float degree = v - 30;
                    float neighborLine = (float) (Math.cos(degree/180f*Math.PI) * mLongLine);
                    float x = mRadius - neighborLine;
                    float duiLine = (float) (Math.sin(degree/180f*Math.PI) * mLongLine);
                    float y = mRadius - duiLine;
                    canvas.drawText(text,x ,y + textWidth /2, mTextPaint );
                } else if (v <= 210) {
                    float degree = v - 120;
                    float neighborLine = (float) Math.cos(degree/180f*Math.PI) * mLongLine;
                    float y = mRadius - neighborLine;
                    float duiLine = (float) (Math.sin(degree/180f*Math.PI) * mLongLine);
                    float x = mRadius + duiLine;
                    canvas.drawText(text,x - textWidth,y + textWidth /2, mTextPaint );
                }else {
                    float degree = v - 210;
                    float neighborLine = (float) Math.cos(degree/180f*Math.PI) * mLongLine;
                    float x = mRadius + neighborLine;
                    float duiLine = (float) (Math.sin(degree/180f*Math.PI) * mLongLine);
                    float y = mRadius + duiLine;
                    canvas.drawText(text,x - textWidth,y , mTextPaint );
                }
            }
        }
    }


    private void drawPointer(Canvas canvas) {
        canvas.save();
        canvas.rotate(-30,mRadius,mRadius);
        float currentDegree = mCurrentScale * singleScaleAngle;
        canvas.rotate(currentDegree,mRadius,mRadius);

//        pointerPath.moveTo(16,mRadius);
//        pointerPath.lineTo(20,mRadius - 10);
//        pointerPath.lineTo(20,mRadius + 10);
//        pointerPath.close();
//        canvas.drawPath(pointerPath,mTextPaint);
//        画指针，一条线
//        canvas.drawLine(25,mRadius,mRadius - 10,mRadius,mTextPaint);
//        画指针，一个小圆球
        mIndicatorDesRect = new Rect(30,mRadius-7,44,mRadius+7);
        canvas.drawBitmap(mIndicatorImg,mIndicatorSrcRect,mIndicatorDesRect,null);
//        canvas.drawCircle(25,mRadius,2,mTextPaint);
        canvas.restore();
    }

    private void drawScale(Canvas canvas) {
        canvas.save();
        canvas.rotate(-30,mRadius,mRadius);
        for (int i = 0; i < mMaxScale + 1; i++) {
            if ((i) % 5 == 0) {
                canvas.drawLine(0, mRadius, 10, mRadius, mScalePaint);
//                canvas.drawText(i + "", 13, mRadius, mTextPaint);
//                drawPointerText(canvas, i);
            } else {
                canvas.drawLine(0, mRadius, 7, mRadius, mScalePaint);
            }
            canvas.rotate(singleScaleAngle, mRadius, mRadius);
        }
        canvas.restore();
    }

    public void setScale(int scale){
        mCurrentScale = scale;
//        if (onScaleChangeListener != null) {
//            onScaleChangeListener.onScaleChanged(mCurrentScale);
//        }
        invalidate();
    }


    private float eventX ; //手指按下的X坐标
    private float eventY ; //手指按下的Y坐标
    @Override
    public boolean onTouchEvent(MotionEvent event) {
//        mEvent = event.getAction();
        if (isEnabled()) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                    //此处使用 getRawX，而不是 getX
                    eventX = event.getX();
                    eventY = event.getY();
                    float[] pts = {eventX,eventY};
                    changeCanvasXY(pts);
                    invalidate();
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    //让指针指向最近的数据，不需要则可注释
//                float surplus = mSweepAngle % (sweepAngle / mSection);
//                int num = (int)((mSweepAngle - surplus) / (sweepAngle / mSection));
//                if(TextUtils.isEmpty(mTexts[num])&&!TextUtils.isEmpty(mTexts[num+1])){
//                    mSweepAngle = mSweepAngle + (sweepAngle / mSection) - surplus;
//                }else if(!TextUtils.isEmpty(mTexts[num])){
//                    mSweepAngle = mSweepAngle - surplus;
//                }
//                invalidate();
                    break;
            }
            return true;
        }
        return false;
    }

    private void changeCanvasXY(float[] pts){
        // 获得当前矩阵的逆矩阵
//        Matrix invertMatrix = new Matrix();
//        canvas.getMatrix().invert(invertMatrix);
        // 使用 mapPoints 将触摸位置转换为画布坐标
//        invertMatrix.mapPoints(pts);
        float x = Math.abs(pts[0]);
        float y = Math.abs(pts[1]);
        double z = Math.sqrt(x*x+y*y);
//        float round1 = (float)(Math.asin(y/z)/Math.PI*180);
//        Log.e("12121","触摸的点：X==="+pts[0]+" Y==="+pts[1]);

        float realX = pts[0] - mRadius;
        float realY = mRadius - pts[1];
        float realZ = (float) Math.sqrt(realX*realX+realY*realY);

        float round = (float) (Math.asin(realY/realZ)/Math.PI*180);

        if(realX <= 0){
            int i = (int) ((round + 30) / singleScaleAngle);
            if (i < 0) {
                i = 0;
            }
            if (i != mCurrentScale) {
                mCurrentScale = i;
                if (onScaleChangeListener != null) {
                    onScaleChangeListener.onScaleChanged(mCurrentScale);
                }
            }

        }else{
            int i = (int) ((210 - round) / singleScaleAngle);
            if (i > mMaxScale) {
                i = mMaxScale;
            }
            if (i != mCurrentScale){
                mCurrentScale = i;
                if (onScaleChangeListener != null) {
                    onScaleChangeListener.onScaleChanged(mCurrentScale);
                }
            }
        }
    }
    OnScaleChangeListener onScaleChangeListener;
    public void setOnScaleChangeListener(OnScaleChangeListener onScaleChangeListener){
        this.onScaleChangeListener = onScaleChangeListener;
    }

    public interface OnScaleChangeListener{
        void onScaleChanged(int scale);
    }

    private void onMaxScaleChanged(){
        singleScaleAngle = (float) (360 - openAngle) / (mMaxScale -1);
    }

    public void setMaxScale(int maxScale) {
        if (mMaxScale == maxScale) {
            return;
        }
        if (mCurrentScale > maxScale) {
            mCurrentScale = maxScale;
        }
        mMaxScale = maxScale;
        onMaxScaleChanged();
        invalidate();
    }
}
